package com.hqd.jjvm.instructions.store;

import com.hqd.jjvm.instructions.AbstractInstruction;
import com.hqd.jjvm.instructions.InstructionType;
import com.hqd.jjvm.rtda.JThread;
import com.hqd.jjvm.rtda.obj.JObject;

public class StoreInstruction extends AbstractInstruction {


    public StoreInstruction(JThread jThread) {
        super(jThread);
    }

    @Override
    public void execute(InstructionType instructionType) {
        Object val = popOperandStackVal();
        switch (instructionType) {
            case ISTORE: {
                Integer localVarIndex = parseAndReadValU1();
                setLocalVarsIntVal(localVarIndex, (Integer) val);
                break;
            }
            case FSTORE: {
                Integer localVarIndex = parseAndReadValU1();
                setLocalVarsFloatVal(localVarIndex, (Float) val);
                break;
            }
            case LSTORE: {
                Integer localVarIndex = parseAndReadValU1();
                setLocalVarsLongVal(localVarIndex, (Long) val);
                break;
            }
            case DSTORE: {
                Integer localVarIndex = parseAndReadValU1();
                setLocalVarsDoubleVal(localVarIndex, (Double) val);
                break;
            }
            case ASTORE: {
                try {
                    Integer localVarIndex = parseAndReadValU1();
                    setLocalVarsRefVal(localVarIndex, (JObject) val);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            }
            case ISTORE_0: {
                setLocalVarsIntVal(0, (Integer) val);
                break;
            }
            case ISTORE_1: {
                setLocalVarsIntVal(1, (Integer) val);
                break;
            }
            case ISTORE_2: {
                setLocalVarsIntVal(2, (Integer) val);
                break;
            }
            case ISTORE_3: {
                setLocalVarsIntVal(3, (Integer) val);
                break;
            }
            case LSTORE_0: {
                setLocalVarsLongVal(0, (Long) val);
                break;
            }
            case LSTORE_1: {
                setLocalVarsLongVal(1, (Long) val);
                break;
            }
            case LSTORE_2: {
                setLocalVarsLongVal(2, (Long) val);
                break;
            }
            case LSTORE_3: {
                setLocalVarsLongVal(3, (Long) val);
                break;
            }
            case FSTORE_0: {
                setLocalVarsFloatVal(0, (Float) val);
                break;
            }
            case FSTORE_1: {
                setLocalVarsFloatVal(1, (Float) val);
                break;
            }
            case FSTORE_2: {
                setLocalVarsFloatVal(2, (Float) val);
                break;
            }
            case FSTORE_3: {
                setLocalVarsFloatVal(3, (Float) val);
                break;
            }
            case DSTORE_0: {
                setLocalVarsDoubleVal(0, (Double) val);
                break;
            }
            case DSTORE_1: {
                setLocalVarsDoubleVal(1, (Double) val);
                break;
            }
            case DSTORE_2: {
                setLocalVarsDoubleVal(2, (Double) val);
                break;
            }
            case DSTORE_3: {
                setLocalVarsDoubleVal(3, (Double) val);
                break;
            }
            case ASTORE_0: {
                setLocalVarsRefVal(0, (JObject) val);
                break;
            }
            case ASTORE_1: {
                setLocalVarsRefVal(1, (JObject) val);
                break;
            }
            case ASTORE_2: {
                setLocalVarsRefVal(2, (JObject) val);
                break;
            }
            case ASTORE_3: {
                setLocalVarsRefVal(3, (JObject) val);
                break;
            }
            case IASTORE: {
                int index = popOperandStackIntVal();
                JObject arrRef = popOperandStackRefVal();
                int[] refs = (int[]) arrRef.getData();
                refs[index] = (int) val;
                break;
            }
            case LASTORE:
            case FASTORE:
            case DASTORE:
            case AASTORE: {
                int index = popOperandStackIntVal();
                JObject arrRef = popOperandStackRefVal();
                JObject[] refs = (JObject[]) arrRef.getData();
                refs[index] = (JObject) val;
                break;
            }
            case BASTORE: {
                int index = popOperandStackIntVal();
                JObject jObject = popOperandStackRefVal();
                byte[] data = (byte[]) jObject.getData();
                data[index] = ((Integer) val).byteValue();
                break;
            }
            case CASTORE: {
                int index = popOperandStackIntVal();
                JObject jObject = popOperandStackRefVal();
                char[] data = (char[]) jObject.getData();
                data[index] = (char) ((Integer) val).intValue();
                break;
            }
            case SASTORE:
                break;
        }
    }
}
